﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using ScrumTable.Common;
using ScrumTable.Common.Collections;
using ScrumTable.DL.Data.Schema;

#endregion

namespace ScrumTable.DL.Data.Generic.Cache
{
    /// <summary>
    /// Represents a transition wrapper with transition state management in
    /// conjunction with the workflow facilities of work items.
    /// </summary>
    public class CacheTransition : CacheElementBase
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the transition FROM a state to another state.
        /// </summary>
        public string From { get; private set; }

        /// <summary>
        /// Gets the transition from a state TO another state.
        /// </summary>
        public string To { get; private set; }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Initializes a new instance of the <see cref="CacheTransition"/> class.
        /// </summary>
        /// <param name="uniqueId">Specifies the unique id of the current transition.</param>
        /// <param name="transitionStateFrom">Specifies the transition FROM a state to another state.</param>
        /// <param name="transitionStateTo">Specifies the transition from a state TO another state.</param>
        internal CacheTransition(
            string uniqueId,
            string transitionStateFrom,
            string transitionStateTo)
            : base(uniqueId, CacheIdentity.DefaultId, CacheIdentity.DefaultUniqueId, CacheIdentity.DefaultRevision)
        {
            PreCondition.AssertNotNull(transitionStateFrom, "transitionStateFrom");
            PreCondition.AssertNotNull(transitionStateTo, "transitionStateTo");

            From = transitionStateFrom;
            To = transitionStateTo;
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        internal static IEnumerable<CacheTransition> LoadTransitionsFromSchema(CacheElementFactory cacheElementFactory, SchemaBase stateSchema)
        {
            PreCondition.AssertNotNull(cacheElementFactory, "cacheElementFactory");

            if (stateSchema != null && stateSchema.HasSchemaAllowedValues)
            {
                return cacheElementFactory.CreateTransitions(stateSchema.SchemaAllowedValues);
            }
            return new CacheTransition[0];
        }

        internal static IEnumerable<CacheTransition> LoadTransitionsFromValues(CacheElementFactory cacheElementFactory, IEnumerable<string> allowedTransitions)
        {
            PreCondition.AssertNotNull(cacheElementFactory, "cacheElementFactory");
            PreCondition.AssertNotNull(allowedTransitions, "allowedTransitions");

            List<string> values = new List<string>();
            allowedTransitions.ForEach<string>(values.Add);

            IList<CacheTransition> transitions = new List<CacheTransition>();
            string firstTransition = null;
            string lastTransition = null;

            for (int i = 0; i < values.Count; ++i)
            {
                if (i == 0)
                {
                    firstTransition = values[i];
                }
                else if (i == values.Count - 1)
                {
                    lastTransition = values[i];
                }

                for (int j = 0; j < values.Count; ++j)
                {
                    if (i != j) { transitions.Add(cacheElementFactory.CreateTransition(values[i], values[j])); }
                }
            }

            if (!string.IsNullOrEmpty(firstTransition)) { transitions.Add(cacheElementFactory.CreateTransition(string.Empty, firstTransition)); }
            if (!string.IsNullOrEmpty(lastTransition)) { transitions.Add(cacheElementFactory.CreateTransition(lastTransition, string.Empty)); }

            return transitions;
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}